﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security;
using CoyoEden.Models;
using CoyoEden.Web.Data;
using CoyoEden.Web;
using CoyoEden.Web.Controls;
using System.Web;
using Vivasky.Core.Infrastructure;
namespace CoyoEden.Web.Controller
{
	public class VoteController : ControllerBase
	{
		public static Vote Single(Dictionary<string, string> Params, out FeedbackData msg)
		{
			msg = new FeedbackData();
			var user = Params["user"];
			var id = Convert.ToInt32(Params["id"]);
			Vote tempVote = null;
			try
			{
				if (id < 0)
				{
					tempVote = new Vote();
				}
				else
				{
					tempVote = Vote.GetVote(id);
					if (tempVote == null)
					{
						msg.Body = string.Format("<h3>无法获取此投票(编号:{0})的信息.</h3>", id);
					}
				}
			}
			catch (Exception ex)
			{
				ResolveException(ex, out msg);
			}
			return tempVote;
		}

		public static void Update(List<NameValuePair<string, string>> Params, out FeedbackData msg)
		{
			msg = new FeedbackData();
			try
			{
				//need validate user?
				var user = Params.Find(item => item.name == "user").value;

				var id = Convert.ToInt32(Params.Find(item => item.name == "VoteID").value);
				Vote vote = null;
				if (id <= 0)
				{
					vote = new Vote();
					vote.Author = user;
				}
				else
				{
					vote = Vote.Votes.Find(c => c.Id == id);
				}
				vote.Title = Params.Find(item => item.name == "VoteTitle").value;
				vote.Description = Params.Find(item => item.name == "VoteDesc").value;
				var tempValuePair = Params.Find(item => item.name == "VoteMultiple");
				if (string.IsNullOrEmpty(tempValuePair.name))
				{
					vote.IsMultiple = false;
				}
				else {
					vote.IsMultiple = (tempValuePair.value == "on") ? true : false;
				}
				
				vote.Save(out msg);
			}
			catch (Exception ex)
			{
				ResolveException(ex, out msg);
			}
		}
		public static void Delete(Dictionary<string,string> Params,out FeedbackData msg) {
			msg = new FeedbackData();
			try
			{
				var keys = Params["keys"];
				var user = Params["user"];
				List<string> itemIDs = keys.Split('|').ToList();
				//delete categories
				itemIDs.ForEach(c =>
				{
					Vote item = Vote.GetVote(Convert.ToInt32(c));
					item.Delete();
					item.Save();
				});
			}
			catch (Exception ex)
			{
				ResolveException(ex, out msg);
			}
		}
		public static void SelectCategories(Dictionary<string, string> Params, out FeedbackData msg)
		{
			msg = new FeedbackData();
			var currentPage = Convert.ToInt32(Params["CPage"]);
			var rowPerPage = Convert.ToInt32(Params["RPPage"]);
			var fatherID = Convert.ToInt32(Params["FatherID"]);
			var itemViewPath = Params["ViewPath"];

			var allItems = new List<Category>();
			if (fatherID == -1)
			{
				allItems = Category.TopCategories;
			}
			else
			{
				allItems = Category.GetChildren(Category.GetCategory(fatherID));
			}
			//do paging
			SimplePager pager = new SimplePager();
			List<Category> items = null;
			if (allItems != null && allItems.Count > 0)
			{
				pager.PagedList<Category>(allItems, rowPerPage, currentPage, out items);
				//Return first record's id!!.For the purpose of locating the latest record
				msg.Context.Add("TopItemID", items[0].Id);
			}
			else
			{
				pager.CurrentPage = currentPage;
				pager.RowPerPage = rowPerPage;
				pager.RowTotal = 0;
				pager.PageTotal = 0;
				pager.Tip = "没有任何记录可以显示";
			}


			//Load Page view
			ViewManager<SimplePagerViewBase> viewObj = new ViewManager<SimplePagerViewBase>("~/Views/SimplePager.ascx");
			viewObj.Control.Pager = pager;
			msg.Context.Add("PagerHtml", viewObj.Render());

			//Load ITEM view
			ViewManager<CategoryViewBase> itemView = new ViewManager<CategoryViewBase>(itemViewPath);
			itemView.Control.CategoriesShow = items;

			msg.Context.Add("CategoryListHtml", itemView.Render());

			msg.Context.Add("Pager", pager);
		}
		/// <summary>
		/// Select posts candidate for a vote
		/// </summary>
		/// <param name="Params"></param>
		/// <param name="msg"></param>
		public static void SelectPosts(Dictionary<string,string> Params,out FeedbackData msg) {
			msg = new FeedbackData();
			var category = Params["Category"];
			var dateRange = Params["DateRange"].Split('至');
			var maxRecords=Params["Top"];
			var sDate = Convert.ToDateTime(dateRange[0]);
			var eDate = Convert.ToDateTime(dateRange[1]);

			var allItems = Post.GetPostsByCategory(Convert.ToInt32(category));
			if (allItems != null && allItems.Count > 0) {
				allItems = allItems.FindAll(item =>(item.DateCreated.CompareTo(sDate) >= 0) && (item.DateCreated.CompareTo(eDate.AddDays(1))<0));
				if (allItems.Count > 0) {
					allItems = allItems.Take(Convert.ToInt32(maxRecords)).ToList();
				};
			}
			//Select a view to render
			ViewManager<VoteViewBase> vm = new ViewManager<VoteViewBase>("~/Views/VoteDetailVoteItemCandidate.ascx");
			vm.Control.PostsForVote = allItems;
			msg.Body = vm.Render();
		}
		/// <summary>
		/// Add vote items
		/// </summary>
		public static void AddVoteItems(List<NameValuePair<string,string>> Params,out FeedbackData msg) {
			msg = new FeedbackData();
			var voteItems = new List<Rate>();
			Vote vote = null;
			var voteID = Params.Find(item=>item.name=="VoteID").value;
			vote = Vote.GetVote(Convert.ToInt32(voteID));
			try
			{
				Params.ForEach(item =>
				{
					if (item.name == "postsForVote")
					{
						var tempPost = Post.GetPost(Convert.ToInt32(item.value));
						if (tempPost != null)
						{
							var tempRate = vote.VoteItems.Find(obj =>
							{
								if (obj.Memos != null && obj.Memos.Keys.Contains("PostID"))
								{
									if (obj.Memos["PostID"].ToString() == tempPost.Id.ToString())
									{
										return true;
									}
									else
									{
										return false;
									}
								}
								else
								{
									return false;
								}
							});
							if (tempRate == null)
							{
								tempRate = new Rate();
								tempRate.Title = tempPost.Title;
								tempRate.Memos = new Dictionary<string, object>();
								tempRate.Memos.Add("PostID", tempPost.Id);
								tempRate.Memos.Add("PostUrl", tempPost.PermaLink.ToString());
								voteItems.Add(tempRate);
							}
						}// /tempPost!=null
					}
				});
				//insert vote items
				if (voteItems.Count > 0)
				{
					Rate.InsertRates(voteItems);
				}
				else {
					return;
				}
				// /insert vote items

				//update the vote 
				vote.ImportVoteItems(voteItems);

				//update VoteItemList view
				ViewManager<VoteViewBase> vm = new ViewManager<VoteViewBase>("~/Views/VoteDetailVoteItemList.ascx");
				vm.Control.VoteItemsShow = vote.VoteItems;
				msg.Context.Add("VoteItemList",vm.Render());
			}catch(Exception ex){
				ResolveException(ex, out msg);
			}
		}
		public static void DelVoteItem(Dictionary<string,string> Params,out FeedbackData msg) {
			msg = new FeedbackData();
			var voteID = Params["VoteID"];
			var voteItemID = Params["VoteItemID"];

			var vote = Vote.GetVote(Convert.ToInt32(voteID));
			var voteItem = Rate.GetRate(Convert.ToInt32(voteItemID));

			try {
				vote.RemoveVoteItem(voteItem);
				//remove the vote item physically
				voteItem.ForceDelete();
				//update the vote item list 
				ViewManager<VoteViewBase> vm = new ViewManager<VoteViewBase>("~/Views/VoteDetailVoteItemList.ascx");
				vm.Control.VoteItemsShow = vote.VoteItems;
				msg.Context.Add("VoteItemList", vm.Render());
			}catch(Exception ex){
				ResolveException(ex,out msg );
			}
		}// /DelVoteItem
		public static void SelectVotes(Dictionary<string,string> Params,out FeedbackData msg) {

			msg = new FeedbackData();
			var currentPage = Convert.ToInt32(Params["CPage"]);
			var rowPerPage = Convert.ToInt32(Params["RPPage"]);
			var itemViewPath = Params["ViewPath"];
			//Do page
			var allItems = Vote.Votes;

			SimplePager pager = new SimplePager();
			List<Vote> items = null;
			if (allItems != null && allItems.Count > 0)
			{
				pager.PagedList<Vote>(allItems, rowPerPage, currentPage, out items);
				//Return first record's id!!.For the purpose of locating the latest record
				msg.Context.Add("TopItemID", items[0].Id);
				//Load Page view
				ViewManager<SimplePagerViewBase> viewObj = new ViewManager<SimplePagerViewBase>("~/Views/SimplePager.ascx");
				viewObj.Control.Pager = pager;
				msg.Context.Add("PagerHtml", viewObj.Render());
				msg.Context.Add("HasItems", true);
			}
			else
			{
				msg.Context.Add("HasItems", false);
			}




			//Load ITEM view
			ViewManager<VoteViewBase> itemView = new ViewManager<VoteViewBase>(itemViewPath);
			itemView.Control.VotesShow = items;

			msg.Context.Add("VoteListHtml", itemView.Render());

			msg.Context.Add("Pager", pager);

		}// /SelectVotes
		public static void ShowVoteItems(Dictionary<string,string> Params,out FeedbackData msg) {
			msg = new FeedbackData();
			var voteID = Params["id"];
			var vote = Vote.GetVote(Convert.ToInt32(voteID));

			var viewPath = ViewBase.GetViewPath(HttpContext.Current.Request, "RateListView");
			//Render a view
			ViewManager<VoteViewBase> vm = new ViewManager<VoteViewBase>(viewPath);
			vm.Control.TheVote = vote;
			vm.Control.VoteItemsShow = vote.VoteItems;
			msg.Body = vm.Render();
		} // /ShowVoteItems
		/// <summary>
		/// Do Vote
		/// </summary>
		/// <param name="Params"></param>
		/// <param name="msg"></param>
		public static void DoVote(List<NameValuePair<string, string>> Params, out FeedbackData msg) {
			msg = new FeedbackData();
			var voteItems = new List<Rate>();
			Vote vote = null;
			var voteID = Convert.ToInt32(Params.Find(item => item.name == "VoteID").value);
			vote = Vote.GetVote(voteID);
			//Get Current request's Ip
			var ip = Utils.GetIP();
			//whether has voted
			if (HasVoted(voteID)||vote.IncludeRater(ip)) {
				msg.IsOk = false;
				msg.Body = "你已经投过票了";
				return;
			}
			//vote proccess
			Params.ForEach(item => {
				if (item.name == "rateItems") {
					var tempRate = vote.VoteItems.Find(obj=>obj.Id.ToString()==item.value);
					if (tempRate != null) {
						vote.VoteItems.Remove(tempRate);
						tempRate.Hits++;
						tempRate.RaterList.Add(ip);

						vote.VoteItems.Add(tempRate);
						voteItems.Add(tempRate);
					}
				}
			});
			//batch update rates without raise extension event handler
			try {
				Rate.UpdateRates(voteItems);
				//update current vote's hits
				msg.Context.Add("Hits",vote.GetVoteHits());
				//update cookie
				SetVotingCookie(voteID.ToString(), HttpContext.Current);
			}catch(Exception ex){
				ResolveException(ex, out msg);
			}

		}// /DoVote

		#region helper methods
		private static bool HasVoted(int voteId) {
			if (HttpContext.Current.Request.Cookies["MBPortalVote"] != null)
			{
				HttpCookie cookie = HttpContext.Current.Request.Cookies["MBPortalVote"];
				return cookie.Value.Contains(voteId.ToString());
			}

			return false;
		}
		private static void SetVotingCookie(string id, HttpContext context)
		{
			HttpCookie cookie;
			if (context.Request.Cookies["MBPortalVote"] != null)
			{
				cookie = context.Request.Cookies["MBPortalVote"];
			}
			else
			{
				cookie = new HttpCookie("MBPortalVote");
			}

			cookie.Expires = DateTime.Now.AddYears(2);
			cookie.Value += "|" + id;
			context.Response.Cookies.Add(cookie);
		}
		#endregion
	}
}

